home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright 1992, 1993, 1994, Silicon Graphics, Inc.
- * All Rights Reserved.
- *
- * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
- * the contents of this file may not be disclosed to third parties, copied or
- * duplicated in any form, in whole or in part, without the prior written
- * permission of Silicon Graphics, Inc.
- *
- * RESTRICTED RIGHTS LEGEND:
- * Use, duplication or disclosure by the Government is subject to restrictions
- * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
- * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
- * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
- * rights reserved under the Copyright Laws of the United States.
- */
-
- /* Tom Davis -- 1992 */
-
- /* draw various 3d models */
-
- #include <stdio.h>
- #include <math.h>
- #include <gl.h>
- #include <device.h>
- #include "3d.h"
-
- #define PI 3.14159265358979
-
- float blackvec[3] = {0.0, 0.0, 0.0};
- float whitevec[3] = {1.0, 1.0, 1.0};
- static float idmat[4][4] = {1.0,0.0,0.0,0.0,
- 0.0,1.0,0.0,0.0,
- 0.0,0.0,1.0,0.0,
- 0.0,0.0,0.0,1.0};
-
- float shiny_material[] = {SPECULAR, 0.8, 0.8, 0.8,
- DIFFUSE, 0.4, 0.4, 0.4,
- SHININESS, 30.0,
- LMNULL};
-
- float purple_material[] = {SPECULAR, 0.3, 0.3, 0.3,
- DIFFUSE, 0.8, 0.0, 0.8,
- SHININESS, 5.0,
- AMBIENT, 0.2, 0.0, 0.2,
- LMNULL};
-
- float material1[] = {SPECULAR, 0.3, 0.3, 0.3,
- DIFFUSE, 0.8, 0.8, 0.8,
- SHININESS, 1.0,
- LMNULL};
-
- float material2[] = {SPECULAR, 0.3, 0.3, 0.8,
- DIFFUSE, 0.0, 0.0, 0.8,
- SHININESS, 2.0,
- AMBIENT, 0.2, 0.0, 0.2,
- LMNULL};
-
- float material3[] = {SPECULAR, 0.3, 0.3, 0.3,
- DIFFUSE, 0.8, 0.0, 0.0,
- SHININESS, 50.0,
- AMBIENT, 0.2, 0.0, 0.0,
- LMNULL};
-
- float material4[] = {SPECULAR, 0.3, 0.3, 0.3,
- DIFFUSE, 0.0, 0.8, 0.8,
- SHININESS, 5.0,
- LMNULL};
-
- float blue_light[] = {LCOLOR, 0.0, 0.0, 0.6,
- POSITION, 0.0, 1.0, 0.0, 0.0,
- LMNULL};
-
- /*
- ** Tell the Graphics Library to DEFINE a simple lighting model
- ** that accounts for diffuse and ambient reflection. This simple
- ** lighting model happens to be the default lighting model for
- ** the Graphics Library.
- */
- void def_simple_light_model()
-
- {
- lmdef(DEFLMODEL, 1, 0, NULL);
- lmdef(DEFMATERIAL, 1, 11, shiny_material);
- lmdef(DEFMATERIAL, 2, 15, purple_material);
- lmdef(DEFMATERIAL, 3, 11, material1);
- lmdef(DEFMATERIAL, 4, 15, material2);
- lmdef(DEFMATERIAL, 5, 15, material3);
- lmdef(DEFMATERIAL, 6, 11, material4);
- lmdef(DEFLIGHT, 1, 0, NULL);
- lmdef(DEFLIGHT, 2, 10, blue_light);
- }
-
- /*
- ** Tell the Graphics Library to USE the simple lighting model
- ** that we defined earlier.
- */
- use_simple_light_model()
-
- {
- lmbind(LMODEL, 1);
- lmbind(LIGHT0, 1);
- lmbind(LIGHT1, 2);
- }
-
- /* Here's an idiotic display list. Just save the vectors and
- * normals in a giant list, and spew them out in order when the
- * draw command comes.
- */
-
- float vectlist[200000][3];
- float normlist[200000][3];
- long vcount;
-
- float trilist[100000][3];
- float trinorm[100000][3];
- long tcount;
-
- void initdisplaylist()
- {
- tcount = vcount = 0;
- }
-
- /* ... and the corresponding idiotic savefunc */
-
- void savefunc(type, n0, v0, n1, v1, n2, v2, n3, v3)
- long type;
- float *n0, *n1, *n2, *n3, *v0, *v1, *v2, *v3;
- {
- if (type == ADD_QUAD) {
- if (vcount > 200000) {
- fprintf(stderr, "too many points\n");
- exit();
- }
- copy3(n0, &normlist[vcount][0]);
- copy3(v0, &vectlist[vcount++][0]);
- copy3(n1, &normlist[vcount][0]);
- copy3(v1, &vectlist[vcount++][0]);
- copy3(n2, &normlist[vcount][0]);
- copy3(v2, &vectlist[vcount++][0]);
- copy3(n3, &normlist[vcount][0]);
- copy3(v3, &vectlist[vcount++][0]);
- } else {
- if (tcount > 100000) {
- fprintf(stderr, "too many points\n");
- exit();
- }
- copy3(n0, &trinorm[tcount][0]);
- copy3(v0, &trilist[tcount++][0]);
- copy3(n1, &trinorm[tcount][0]);
- copy3(v1, &trilist[tcount++][0]);
- copy3(n2, &trinorm[tcount][0]);
- copy3(v2, &trilist[tcount++][0]);
- }
- }
-
- void drawdisplaylist()
- {
- long i;
-
- for (i = 0; i < vcount;) {
- bgnpolygon();
- n3f(&normlist[i][0]);
- v3f(&vectlist[i++][0]);
- n3f(&normlist[i][0]);
- v3f(&vectlist[i++][0]);
- n3f(&normlist[i][0]);
- v3f(&vectlist[i++][0]);
- n3f(&normlist[i][0]);
- v3f(&vectlist[i++][0]);
- endpolygon();
- }
- for (i = 0; i < tcount;) {
- bgnpolygon();
- n3f(&trinorm[i][0]);
- v3f(&trilist[i++][0]);
- n3f(&trinorm[i][0]);
- v3f(&trilist[i++][0]);
- n3f(&trinorm[i][0]);
- v3f(&trilist[i++][0]);
- endpolygon();
- }
- }
-
- void drawworld()
- {
- c3f(blackvec);
- clear();
- zclear();
- drawdisplaylist();
- }
-
- void makeethanol()
- {
- initdisplaylist();
-
- m_resetmatrixstack();
- quadsphere(14, 14, savefunc);
- m_pushmatrix();
- m_scale(.6, .6, .6);
- m_translate(-1.0, -1.0, -1.0);
- quadsphere(16, 16, savefunc);
- m_popmatrix();
- m_pushmatrix();
- m_scale(.6, .6, .6);
- m_translate(1.0, 1.0, -1.0);
- quadsphere(16, 16, savefunc);
- m_popmatrix();
- m_pushmatrix();
- m_scale(.6, .6, .6);
- m_translate(-1.0, 1.0, 1.0);
- quadsphere(16, 16, savefunc);
- m_popmatrix();
- m_pushmatrix();
- m_translate(.8, -.8, .8);
- quadsphere(14, 14, savefunc);
- m_pushmatrix();
- m_scale(.6, .6, .6);
- m_translate(-1.0, -1.0, 1.0);
- quadsphere(16, 16, savefunc);
- m_popmatrix();
- m_pushmatrix();
- m_scale(.6, .6, .6);
- m_translate(1.0, -1.0, -1.0);
- quadsphere(16, 16, savefunc);
- m_popmatrix();
- m_pushmatrix();
- m_scale(.8, .8, .8);
- m_translate(0.7, 0.7, 0.7);
- quadsphere(16, 16, savefunc);
- m_translate(.5, -.5, .5);
- m_scale(.78, .78, .78);
- quadsphere(16, 16, savefunc);
- m_popmatrix();
- m_popmatrix();
- }
-
- void makebenzene()
- {
- long i;
- float theta, t1, t2;
-
- initdisplaylist();
- m_resetmatrixstack();
- for (i = 0; i < 6; i++) {
- theta = i*2.0*PI/6;
- t1 = cos(theta);
- t2 = sin(theta);
- m_pushmatrix();
- m_translate(t1, t2, 0.0);
- quadsphere(12, 12, savefunc);
- m_popmatrix();
- m_pushmatrix();
- m_translate(t1*1.8, t2*1.8, 0.0);
- m_scale(.6, .6, .6);
- quadsphere(14, 14, savefunc);
- m_popmatrix();
- }
- }
-
-
- #define NORMFACTOR 40.0
-
- #define S (200.0/NORMFACTOR) /* side of surrounding cube */
- #define R (18.0/NORMFACTOR) /* cylinder radius == half D, below */
- #define D (2.0*R) /* offset for doubled edges */
- #define SRD (S-(R+D))
- #define NSIDES 12 /* must be multiple of 4 to match at corners */
- #define ELBOWSTEPS 5
-
- float endpts[55][3] = {
- {R-S/2.0, 2*R+D-S/2.0, R-S/2.0},
- {R-S/2.0, R+D-S/2.0, R-S/2.0}, /* corner */
- {2*R-S/2.0, R+D-S/2.0, R-S/2.0},
- {SRD-R-S/2.0, R+D-S/2.0, R-S/2.0},
- {SRD-S/2.0, R+D-S/2.0, R-S/2.0}, /* corner */
- {SRD-S/2.0, 2*R+D-S/2.0, R-S/2.0},
- {SRD-S/2.0, S-2*R-S/2.0, R-S/2.0},
- {SRD-S/2.0, S-R-S/2.0, R-S/2.0}, /* corner */
- {SRD-R-S/2.0, S-R-S/2.0, R-S/2.0},
- {2*R+D-S/2.0, S-R-S/2.0, R-S/2.0},
- {R+D-S/2.0, S-R-S/2.0, R-S/2.0}, /* corner */
- {R+D-S/2.0, S-R-S/2.0, 2*R-S/2.0},
- {R+D-S/2.0, S-R-S/2.0, SRD-R-S/2.0},
- {R+D-S/2.0, S-R-S/2.0, SRD-S/2.0}, /* corner */
- {2*R+D-S/2.0, S-R-S/2.0, SRD-S/2.0},
- {S-2*R-S/2.0, S-R-S/2.0, SRD-S/2.0},
- {S-R-S/2.0, S-R-S/2.0, SRD-S/2.0}, /* corner */
- {S-R-S/2.0, S-R-S/2.0, SRD-R-S/2.0},
- {S-R-S/2.0, S-R-S/2.0, 2*R+D-S/2.0},
- {S-R-S/2.0, S-R-S/2.0, R+D-S/2.0}, /* corner */
- {S-R-S/2.0, S-2*R-S/2.0, R+D-S/2.0},
- {S-R-S/2.0, 2*R+D-S/2.0, R+D-S/2.0},
- {S-R-S/2.0, R+D-S/2.0, R+D-S/2.0}, /* corner */
- {S-R-S/2.0, R+D-S/2.0, 2*R+D-S/2.0},
- {S-R-S/2.0, R+D-S/2.0, S-2*R-S/2.0},
- {S-R-S/2.0, R+D-S/2.0, S-R-S/2.0}, /* corner */
- {S-R-S/2.0, 2*R+D-S/2.0, S-R-S/2.0},
- {S-R-S/2.0, SRD-R-S/2.0, S-R-S/2.0},
- {S-R-S/2.0, SRD-S/2.0, S-R-S/2.0}, /* corner */
- {S-2*R-S/2.0, SRD-S/2.0, S-R-S/2.0},
- {2*R+D-S/2.0, SRD-S/2.0, S-R-S/2.0},
- {R+D-S/2.0, SRD-S/2.0, S-R-S/2.0}, /* corner */
- {R+D-S/2.0, SRD-R-S/2.0, S-R-S/2.0},
- {R+D-S/2.0, 2*R-S/2.0, S-R-S/2.0},
- {R+D-S/2.0, R-S/2.0, S-R-S/2.0}, /* corner */
- {2*R+D-S/2.0, R-S/2.0, S-R-S/2.0},
- {SRD-R-S/2.0, R-S/2.0, S-R-S/2.0},
- {SRD-S/2.0, R-S/2.0, S-R-S/2.0}, /* corner */
- {SRD-S/2.0, R-S/2.0, S-2*R-S/2.0},
- {SRD-S/2.0, R-S/2.0, 2*R+D-S/2.0},
- {SRD-S/2.0, R-S/2.0, R+D-S/2.0}, /* corner */
- {SRD-R-S/2.0, R-S/2.0, R+D-S/2.0},
- {2*R-S/2.0, R-S/2.0, R+D-S/2.0},
- {R-S/2.0, R-S/2.0, R+D-S/2.0}, /* corner */
- {R-S/2.0, R-S/2.0, 2*R+D-S/2.0},
- {R-S/2.0, R-S/2.0, SRD-R-S/2.0},
- {R-S/2.0, R-S/2.0, SRD-S/2.0}, /* corner */
- {R-S/2.0, 2*R-S/2.0, SRD-S/2.0},
- {R-S/2.0, SRD-R-S/2.0, SRD-S/2.0},
- {R-S/2.0, SRD-S/2.0, SRD-S/2.0}, /* corner */
- {R-S/2.0, SRD-S/2.0, SRD-R-S/2.0},
- {R-S/2.0, SRD-S/2.0, 2*R-S/2.0},
- {R-S/2.0, SRD-S/2.0, R-S/2.0}, /* corner */
- {R-S/2.0, SRD-R-S/2.0, R-S/2.0},
- {R-S/2.0, 2*R+D-S/2.0, R-S/2.0}, /* duplicate of 0 */
- };
-
- fixupendpts()
- {
- long i, j;
-
- for (i = 1; i < 54; i += 3)
- for (j = 0; j < 3; j++)
- endpts[i][j] = endpts[i-1][j] + endpts[i+1][j] - endpts[i][j];
- }
-
- makesgilogo()
- {
- long i;
- static long inited = 0;
-
- if (inited == 0) { fixupendpts(); inited = 1; }
- initdisplaylist();
- m_resetmatrixstack();
- for (i = 2; i < 54; i+= 3)
- cylinder(&endpts[i][0], &endpts[i+1][0], R*.99, NSIDES, savefunc);
-
- for (i = 0; i < 54; i += 3)
- elbow(&endpts[i][0], &endpts[i+1][0], &endpts[i+2][0],
- R*.99, NSIDES, 5, savefunc);
- }
-
- float aa[3] = {5.0, -5.0, -5.5};
- float bb[3] = {-5.0, -5.0, -4.5};
- float cc[3] = {-5.0, 5.0, -3.5};
- float dd[3] = {5.0, 5.0, -2.5};
- float ee[3] = {5.0, -5.0, -1.5};
- float ff[3] = {-5.0, -5.0, -0.5};
- float gg[3] = {-5.0, 5.0, 0.5};
- float hh[3] = {5.0, 5.0, 1.5};
- float ii[3] = {5.0, -5.0, 2.5};
- float jj[3] = {-5.0, -5.0, 3.5};
- float kk[3] = {-5.0, 5.0, 4.5};
- float ll[3] = {5.0, 5.0, 5.5};
-
- float zero[3] = {0.0, 0.0, 0.0};
- float one[3] = {1.0, 0.0, 0.0};
-
- makespiral()
- {
- curve_t *c;
-
- initdisplaylist();
- m_resetmatrixstack();
- m_scale(0.5, 0.5, 0.5);
- c = newbsplinecurve(aa, bb, cc, dd);
- makeworm(c, .6, 12, 7, savefunc);
- freecurve(c);
- c = newbsplinecurve(bb, cc, dd, ee);
- makeworm(c, .6, 12, 7, savefunc);
- freecurve(c);
- c = newbsplinecurve(cc, dd, ee, ff);
- makeworm(c, .6, 12, 7, savefunc);
- freecurve(c);
- c = newbsplinecurve(dd, ee, ff, gg);
- makeworm(c, .6, 12, 7, savefunc);
- freecurve(c);
- c = newbsplinecurve(ee, ff, gg, hh);
- makeworm(c, .6, 12, 7, savefunc);
- freecurve(c);
- c = newbsplinecurve(ff, gg, hh, ii);
- makeworm(c, .6, 12, 7, savefunc);
- freecurve(c);
- c = newbsplinecurve(gg, hh, ii, jj);
- makeworm(c, .6, 12, 7, savefunc);
- freecurve(c);
- c = newbsplinecurve(hh, ii, jj, kk);
- makeworm(c, .6, 12, 7, savefunc);
- freecurve(c);
- c = newbsplinecurve(ii, jj, kk, ll);
- makeworm(c, .6, 12, 7, savefunc);
- freecurve(c);
- m_rotate(PI/2.0, 'y');
- doughnut(.4, 3.0, 12, 40, savefunc);
- dodecahedron(zero, 1.0, savefunc);
- }
-
- #define A 5.0
- #define B 3.0
-
- float xx(float t)
- {
- return .3*sin(A*t) + .4*cos(B*t) + 1;
- }
-
- float yy(float t)
- {
- return 2.0*t;
- }
-
- float zz(float t)
- {
- return 0.0;
- }
-
- float xx1(float t)
- {
- return .3*A*cos(A*t) -.4*B*sin(B*t);
- }
-
- float yy1(float t)
- {
- return 2.0;
- }
-
- float zz1(float t)
- {
- return 0.0;
- }
-
- float xx2(float t)
- {
- return -.3*A*A*sin(A*t) -.4*B*B*cos(B*t);
- }
-
- float yy2(float t)
- {
- return 0.0;
- }
-
- float zz2(float t)
- {
- return 0.0;
- }
-
- makesmoothsolidofrevolution()
- {
- pwlin_t *pw;
- curve_t *c;
-
- initdisplaylist();
- m_resetmatrixstack();
- c = newanalyticcurve(xx, yy, zz, xx1, yy1, zz1, xx2, yy2, zz2);
- pw = pwlinfromcurve(c, 40);
- freecurve(c);
- smoothsolidofrevolution(pw, 40, savefunc);
- freepwlin(pw);
- }
-
- float pwdata[] = {
- 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0
- };
-
- makesquareworm()
- {
- pwlin_t *pw;
- curve_t *c;
-
- initdisplaylist();
- m_resetmatrixstack();
- m_scale(0.5, 0.5, 0.5);
- pw = makepwlin(5, pwdata);
- c = newbeziercurve(hh, ii, jj, kk);
- makepwlworm(c, pw, 40, savefunc);
- freecurve(c);
- freepwlin(pw);
- }
-
- float pw1data[] = {
- 0, 0, 0, .2, .2, 0, .5, .2, 0, .5, .5, 0, .2, 1, 0, 0, 1, 0
- };
-
- makesolidofrevolution()
- {
- pwlin_t *pw;
-
- initdisplaylist();
- m_resetmatrixstack();
- m_scale(3.0, 3.0, 3.0);
- pw = makepwlin(6, pw1data);
- solidofrevolution(pw, 40, savefunc);
- freepwlin(pw);
- }
-
- float p1[3] = {-2.0, -2.0, -2.0};
- float p2[3] = {-2.0, 2.0, 2.0};
- float p3[3] = {2.0, -2.0, 2.0};
- float p4[3] = {2.0, 2.0, -2.0};
-
- makeplatonicsolids()
- {
- initdisplaylist();
- m_resetmatrixstack();
- drawbox(-0.5, 0.5, -0.5, 0.5, -0.5, 0.5, savefunc);
- icosahedron(p1, .5, savefunc);
- octahedron(p2, .5, savefunc);
- tetrahedron(p3, .5, savefunc);
- dodecahedron(p4, .5, savefunc);
- }
-
- makewarp()
- {
- initdisplaylist();
- m_resetmatrixstack();
- m_pushmatrix();
- m_shear(2.0, 1.0, 0.0);
- drawbox(-0.5, 0.5, -0.5, 0.5, -0.5, 0.5, savefunc);
- m_popmatrix();
- m_pushmatrix();
- m_translate(2.0, 0.0, 0.0);
- m_scale(.3, 1.0, 1.7);
- trisphere(zero, 1.0, 4, savefunc);
- m_popmatrix();
- m_pushmatrix();
- m_translate(-2.0, 0.0, 0.0);
- m_rotate(PI/4.0, 'x');
- m_rotate(PI/3.0, 'z');
- cylinder(zero, one, 0.3, 12, savefunc);
- m_popmatrix();
- }
-
- static long menu, materials, models;
-
- initmenus()
- {
- materials = defpup("Shiny%x1|Purple%x2|Chalk%x3|Blue%x4|Red Plastic%x5|Cyan%x6");
- models = defpup("Ethanol%x100|SGI Logo%x101|Benzene%x102|Spiral%x103");
- addtopup(models, "Solid of Revolution%x107");
- addtopup(models, "Smooth Solid of Rev.%x104|Square Worm%x105|Platonic Solids%x106");
- addtopup(models, "Warped Stuff%x108");
- menu = defpup("Models %m|Materials %m|Save Spin%x999|Quit%x1000", models, materials);
- }
-
- main(int argc, char **argv)
- {
- long model = 1;
- long material = 1;
- long cmd;
-
- keepaspect(1, 1);
- foreground();
- winopen("worm");
- backface(1);
- RGBmode();
- doublebuffer();
- zbuffer(TRUE);
- gconfig();
- mmode(MVIEWING);
- perspective(450, 1.0, 1.0, 1000.0);
- def_simple_light_model();
- use_simple_light_model();
- initmenus();
- makeethanol();
- lmbind(MATERIAL, material);
- while (1) {
- if (getbutton(RIGHTMOUSE)) {
- cmd = dopup(menu);
- if (cmd > 0 && cmd <= 6)
- lmbind(MATERIAL, material = cmd);
- else switch (cmd) {
- case 100:
- makeethanol();
- break;
- case 101:
- makesgilogo();
- break;
- case 102:
- makebenzene();
- break;
- case 103:
- makespiral();
- break;
- case 104:
- makesmoothsolidofrevolution();
- break;
- case 105:
- makesquareworm();
- break;
- case 106:
- makeplatonicsolids();
- break;
- case 107:
- makesolidofrevolution();
- break;
- case 108:
- makewarp();
- break;
- case 999:
- /*
- savetospinfile();
- */
- break;
- case 1000:
- return;
- }
- }
- trackmodel(drawworld, 15.0, 0.0, 0.0, 0.0);
- }
- }
-
- FILE *binfile;
-
- xsavetospinfile()
- {
- long i;
-
- for (i = 0; i < vcount; i++) {
- printf("{%g, %g, %g},\n", vectlist[i][0], vectlist[i][1], vectlist[i][2]);
- }
- fflush(stdout);
- return;
- }
-
- savetospinfile()
- {
- long i;
-
- openfile(vcount + (tcount*4)/3);
- for (i = 0; i < vcount; i++) {
- fwrite(&normlist[i][0], 4, 3, binfile);
- fwrite(&vectlist[i][0], 4, 3, binfile);
- }
- for (i = 0; i < tcount;) { /* hack!!!! write triangle as quad */
- fwrite(&trinorm[i][0], 4, 3, binfile);
- fwrite(&trilist[i++][0], 4, 3, binfile);
- fwrite(&trinorm[i][0], 4, 3, binfile);
- fwrite(&trilist[i++][0], 4, 3, binfile);
- fwrite(&trinorm[i][0], 4, 3, binfile);
- fwrite(&trilist[i][0], 4, 3, binfile);
- fwrite(&trinorm[i][0], 4, 3, binfile);
- fwrite(&trilist[i++][0], 4, 3, binfile);
- }
- fclose(binfile);
- return;
- }
-
- openfile(long pcount)
- {
- long magic[3];
-
- magic[0] = 0x5423;
- magic[1] = pcount*4;
- magic[2] = 0; /* no color values */
-
- if ((binfile = fopen("model.spin", "w")) == 0) {
- fprintf(stderr, "couldn't open model.sgo\n");
- return;
- }
- fwrite(magic, 4, 3, binfile);
- }
-
-
-
-
-